package com.browsesoft.baseadapter;

import java.io.Serializable;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import com.aote.serialnumber.IncreaseSerialFactory;
import com.browsesoft.Entity;
import com.browsesoft.EntityManager;
import com.browsesoft.ExtendElement;
import com.browsesoft.PropertiesService;
import com.browsesoft.SequenceFind;
import com.browsesoft.htmlcomponent.HTMLBasicComponent;
import com.browsesoft.htmlcomponent.HTMLFormComponent;
import com.browsesoft.htmlcomponent.HTMLFormModel;
import com.browsesoft.log.OperateLog;
import com.browsesoft.tools.BSCalendar;
import com.browsesoft.user.User;

/**
 * 简单实体相当于原来的HTMLDBTableModel
 */
public class SimpleEntity extends BasicEntity implements HTMLFormModel,
		EntityListAttrDispose, Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = -350048470183367579L;

	/**
	 * 基本组件
	 */
	public transient HTMLBasicComponent BasicComponent;

	/**
	 * 父id
	 */
	protected String parentID = null;

	/**
	 * 请求里传递的id号，有id时，不是插入
	 */
	private String requestId = null;

	/**
	 * 动作
	 */
	protected String action = null;

	/**
	 * 登录用户
	 */
	protected User loginUser;

	private Hashtable orginData = new Hashtable();

	private String otherAction = null;

	/**
	 * 构造
	 */
	public SimpleEntity() {
	}

	/**
	 * 构造
	 * 
	 * @param attr
	 *            属性
	 */
	public SimpleEntity(Hashtable attr) {
		super(attr);
	}

	/**
	 * 得到选项值
	 * 
	 * @param name
	 *            名字
	 * @return nullsww
	 * @throws Exception
	 */
	public Iterator getOptions(String name) throws Exception {
		return null;
	}

	/**
	 * 更新页面元素
	 * 
	 * @param hTMLBasicComponent
	 *            基本组件
	 * @throws Exception
	 */
	public void updatePageElement(HTMLBasicComponent hTMLBasicComponent)
			throws Exception {
	}

	/**
	 * 初始化页面
	 * 
	 * @param request
	 *            请求
	 * @throws Exception
	 */
	public void init(HttpServletRequest request) throws Exception {
		loginUser = (User) request.getSession().getAttribute("loginUser");
		orginData.putAll(this.getAttributes());
		// 组件元素
		Element e = this.BasicComponent.getElement();
		// 得到表名
		this.tableName = e.getAttribute("tablename");
		this.entityType = getEntityType(e);
		// 得到父id
		this.parentID = request.getParameter("parentid");
		// 请求里穿过来的id，请求里有id，不是插入
		this.requestId = request.getParameter("id");
	}

	/**
	 * 默认的得到实体类型，子类可以重载该方法，以不同的形式返回实体类型
	 */
	protected String getEntityType(Element e) {
		// 得到实体类型
		String entityType = e.getAttribute("entitytype");
		if (entityType == null || entityType.equals("")) {
			throw new TemplateMissedEntityTypeException("模版缺少实体类型:"
					+ this.BasicComponent.getPage().getTempalteName());
		}
		return entityType;
	}

	/**
	 * 设置组件
	 * 
	 * @param BasicComponent
	 *            基本组件
	 */
	public void setComponent(HTMLBasicComponent BasicComponent) {
		this.BasicComponent = BasicComponent;
	}

	/**
	 * 设置登录用户
	 * 
	 * @param loginUser
	 *            登录用户
	 */
	public void setLoginUser(User loginUser) {
		this.loginUser = loginUser;
	}

	/**
	 * 页面服务
	 * 
	 * @param httpServletResponse
	 *            响应
	 * @throws Exception
	 */
	public void service(HttpServletRequest request,
			HttpServletResponse httpServletResponse) throws Exception {
		this.otherAction = request.getParameter("otheraction");
		this.action = request.getParameter("action");
		// 如果是第一次请求
		if (this.action != null && this.action.equalsIgnoreCase("return")) {
			this.attributes = orginData;
		}
		String t = request.getParameter("templatename");
		if (t != null) {
			// 组件元素
			Element e = this.BasicComponent.getElement();
			// 得到表名
			this.tableName = e.getAttribute("tablename");
			// 得到实体类型
			this.entityType = e.getAttribute("entitytype");
			// 得到父id
			this.parentID = request.getParameter("parentid");
		}
		// 如果parentid是从树中传过来的
		if (this.parentID != null && !this.parentID.equals("null")
				&& !this.parentID.equals("nodeid")) {
			// 得到父
			Entity entity = (Entity) EntityManager.getInstance().getObject(
					this.parentID);
			try {
				// 设置本实体的f_parentname为父的名字
				String name = (String) entity.getAttributes().get("name");
				this.attributes.put("f_parentname", name);
			}
			// 父没有名称
			catch (Exception ex) {
				// 不设
			}
		}
		this.userIdToName();
		// 向属性userid中放入用户id号
		String userid = (String) this.getAttributes().get("userid");
		if (userid == null || userid.equals("")) {
			// 得到user="loginuser"标记
			String str = (String) this.BasicComponent.getElement()
					.getAttribute("user");
			// 如果不为空
			if (str != null && str.equals("loginuser")) {
				// 将用户id号放入隐藏域中
				String id = loginUser.getID();
				this.attributes.put("userid", id);
			}
		}
	}

	/**
	 * 是否配置了不进行userId的转化
	 */
	private boolean notTransUserId() {
		// 如果配置了不进行用户id号到名称的转化过程，直接返回
		try {
			String notTrans = PropertiesService.getProperty("SimpleEntity",
					"notTransUserId");
			if (notTrans != null && !notTrans.equals("")) {
				return true;
			}
			return false;
		} catch (Exception e) {
			return false;
		}
	}

	/**
	 * 把属性里的userid转化成username
	 * 
	 * @return
	 */
	private void userIdToName() {
		if (this.notTransUserId()) {
			return;
		}
		// 根据属性userid显示对应的用户名
		String userid = (String) this.getAttributes().get("userid");
		if (userid != null && !userid.equals("")) {
			User user = (User) EntityManager.getInstance().getObject(userid);
			// 得到录入的用户名
			String name = user.getName();
			// 放入属性,用来显示
			this.attributes.put("f_user", name);
		}
	}

	/**
	 * 删除内容
	 * 
	 * @throws java.lang.Exception
	 */
	public void delete() throws java.lang.Exception {
		this.delete(true);
	}

	/**
	 * 删除内容
	 * 
	 * @param log
	 *            是否做删除日志
	 * @throws java.lang.Exception
	 */
	public void delete(boolean log) throws java.lang.Exception {
		super.delete();
		// 如果需要做删除日志
		if (log) {
			if (this.loginUser != null) {
				OperateLog operateLog = new OperateLog();
				operateLog.deleteLog(loginUser, this);
			}
		}
	}

	/**
	 * 更新属性
	 * 
	 * @param hashtable
	 *            属性集
	 * @throws Exception
	 */
	public void updateAttributes(Hashtable hashtable) throws Exception {
		// 不是刷新动作，把内容放到实体中
		if (this.action == null || !this.action.equals("refresh")) {
			this.getAttributes().putAll(hashtable);
		}
		// 处理属性
		this.processAttributes(hashtable);
		// 如果应该插入
		if (isShouldInsert()) {
			insertEntity();
			// 更新集合属性处理
			updateListAttr("insert");
		}
		// 如果应该更新数据库
		else if (isShouldUpdate()) {
			// 更新数据库
			this.update();
		}
	}

	/**
	 * 由后代对属性进行处理，如表达式计算等
	 */
	protected void processAttributes(Hashtable hashtable) {
	}

	/**
	 * 更新集合属性
	 */
	private void updateListAttr(String action) {
		// 如果页面配置有集合属性配置，进行集合属性处理
		NodeList list = this.BasicComponent.getElement().getElementsByTagName(
				"listAttr");
		if (list.getLength() > 0) {
			Element elem = (Element) list.item(0);
			this.ListAttrDispose(action, this, elem);
		}
	}

	/**
	 * 插入实体
	 */
	private void insertEntity() throws Exception {
		// 把父id放入属性
		if (this.parentID != null) {
			this.getAttributes().put("parentid", parentID);
		}
		// 把类型放入属性
		this.getAttributes().put("entitytype", this.entityType);
		// 把表名放入属性
		this.getAttributes().put("tablename", this.tableName);
		// 创建关系
		this.createRelation();
		// 插入数据库
		if (this.otherAction == null || !this.otherAction.equals("save")) {
			this.disposeSerialNumber();
		}
		this.insert();
	}

	private void disposeSerialNumber() {
		String result = new String();
		this.numbers = IncreaseSerialFactory.getInstance().updateSerialNumber(
				this.getID());
		if (this.numbers == null || this.numbers.isEmpty()) {
			return;
		}
		Iterator iter = this.numbers.entrySet().iterator();
		while (iter.hasNext()) {
			Map.Entry entry = (Map.Entry) iter.next();
			if (result == null || result.equals("")) {
				result = (String) entry.getKey() + ":"
						+ (String) entry.getValue();
			} else {
				result = result + ";" + (String) entry.getKey() + ":"
						+ entry.getValue();
			}
		}
		if (result != null || !result.equals("")) {
			this.attributes.put("abonumber", result);
		}
	}

	/**
	 * 看是否需要插入
	 * 
	 */
	protected boolean isShouldInsert() {
		// 如果有action
		Element e = this.BasicComponent.getElement();
		Iterator iter = ExtendElement.findElements(e, "name", "action")
				.iterator();
		if (iter.hasNext()) {
			// 如果有parentID,并且action的值为"confirm"，并且请求里没有id
			if (parentID != null && !parentID.equals("") && action != null
					&& (action.equals("confirm") || action.equals("next"))
					&& (this.requestId == null || this.requestId.equals(""))) {
				return true;
			}
		}
		// 否则,如果有parentID
		else if (parentID != null && !parentID.equals("")) {
			return true;
		}
		return false;
	}

	/**
	 * 决定是否应该更新数据库
	 */
	protected boolean isShouldUpdate() {
		// 如果页面有action
		Element e = this.BasicComponent.getElement();
		Iterator iter = ExtendElement.findElements(e, "name", "action")
				.iterator();
		if (iter.hasNext()) {
			// 如果action的值不为"confirm"
			if (action == null
					|| (!action.equals("confirm") && !action.equals("continue"))) {
				return false;
			}
		}
		return true;
	}

	/**
	 * 根据页面上的“resourcefrom”属性值来源取实体的属性
	 * 
	 * @param entity
	 *            实体
	 * @return 属性集
	 * @throws Exception
	 */
	public Hashtable getObjectAtt(Entity entity) throws Exception {
		Hashtable result = new Hashtable();
		// 从页面上取属性
		LinkedList ls = ExtendElement.findElements(BasicComponent.getElement(),
				"resourcefrom", "resourcefrom");
		Iterator iter = ls.iterator();
		while (iter.hasNext()) {
			Element e = (Element) iter.next();
			String resource = e.getAttribute("name");
			Object o = entity.getAttributes().get(resource);
			if (o != null) {
				result.put(resource, o);
			}
		}
		// 从实体中取属性
		return result;
	}

	/**
	 * 得到组件
	 */
	public HTMLFormComponent getComponent() {
		return (HTMLFormComponent) this.BasicComponent;
	}

	/**
	 * 判断登录用户的id号与对象中保存操作用户的id号是否相等
	 * 
	 * @param id
	 *            登录用户的id号
	 * @return 是否相等
	 */
	public boolean isEqualsUser(String id) {
		String userid = (String) this.getAttributes().get("userid");
		if (userid != null && userid.equals(id)) {
			return true;
		}
		return false;
	}

	/**
	 * 判断是否与给定的属性名与属性值相等
	 * 
	 * @param name
	 *            给定的属性名
	 * @param value
	 *            给定的属性值
	 * @return 是否相等
	 */
	public boolean isEquals(String name, String value) {
		String str = (String) this.getAttributes().get(name);
		if (str != null && str.equals(value)) {
			return true;
		}
		return false;
	}

	/**
	 * 判断对象中的日期 是否是今天
	 * 
	 * @return 是否是今天的日程
	 */
	public boolean isToday(String fieldname, String format) {
		String starttime = (String) this.getAttributes().get(fieldname);
		starttime = starttime.substring(0, format.length());
		String today = BSCalendar.now().toString(format);
		if (starttime != null && starttime.equals(today)) {
			return true;
		}
		return false;
	}

	/**
	 * 得到parentId
	 */
	public String getParentId() {
		return this.parentID;
	}
	
	

	/**
	 * 实体关联的集合属性处理
	 */
	public void ListAttrDispose(String action, Entity parent, Element configElem) {
		try {
			// 当action="confirm"时，插入一条关联记录
			if (action != null && action.equals("insert")) {
				// 创建实体并插入
				Entity entity = this.createListEntity(parent, configElem);
				entity.insert();
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * 创建关联实体
	 */
	private Entity createListEntity(Entity parent, Element configElem) {
		// 得到实体类型，表明，父id,属性
		Hashtable attrs = new Hashtable();
		String tableName = configElem.getAttribute("tablename");
		String entityType = configElem.getAttribute("entitytype");
		String parentId = parent.getID();
		attrs.put("tablename", tableName);
		attrs.put("entitytype", entityType);
		attrs.put("parentid", parentId);
		// 放入配置的属性
		NodeList list = configElem.getElementsByTagName("attrmap");
		for (int i = 0; i < list.getLength(); i++) {
			Element elem = (Element) list.item(i);
			String source = elem.getAttribute("source");
			String value = (String) parent.getAttributes().get(source);
			if (value == null) {
				value = "";
			}
			String save = elem.getAttribute("save");
			String defaultValue = elem.getAttribute("value");
			if (defaultValue != null && !defaultValue.equals("")) {
				value = elem.getAttribute("value");
			}
			attrs.put(save, value);
		}
		// 创建对象
		String className = configElem.getAttribute("classname");
		return (Entity) EntityManager.newObject(className, attrs);
	}

	/**
	 * 只复制单层属性
	 */
	public Object clone() {
		try {
			Hashtable map = (Hashtable) this.attributes.clone();
			map.put("id", SequenceFind.getID() + "");
			SimpleEntity result = new SimpleEntity(map);
			return result;
		} catch (Exception e) {
			throw new RuntimeException();
		}
	}
}
